package com.awise.app.timer.activity;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.Toast;

import com.awise.R;
import com.awise.base.BaseActivity;
import com.awise.http.RoverGlobal;
import com.awise.util.Constant;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by lihaifeng on 2018/1/24.
 */

public class TimerActivity extends BaseActivity implements View.OnClickListener, ChartView.CurrentXChangeedListener{

    private static final int REQREST_CODE = 10;

    private ChartView mChartView;
    private ImageView mBack;
    private ImageView mAdd;
    private ImageView mRemove;
    private ImageView mPrevious;
    private ImageView mNext;
    private ImageView mPlay;
    private ImageView mPause;
    private ImageView mDownload;
    private ImageView mDelete;
    private Switch mOnOff;
    private int brightnessCount = 5;

    private ArrayList<FrameData> frames;
    private byte power;
    private byte weeks;
    private byte timerId = 0x01;
    private CheckBox monday;
    private CheckBox tuesday;
    private CheckBox wednesday;
    private CheckBox thursday;
    private CheckBox friday;
    private CheckBox saturday;
    private CheckBox sunday;
    private CheckBox all;
    private Button cancel;
    private Button download;

    private int count;
    private boolean chartCanTouch = true;
    private Timer timer;
    private static final String LOGCAT = "TimerActivity";
    private boolean isDisplay;

    private Handler handler = new Handler();
    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == Constant.TIMER_ACTION) {
                byte[] buffer = intent.getByteArrayExtra("socket_data");
                Log.d(LOGCAT, "" + buffer.length);
                if (buffer != null) {
                    byte comman1 = buffer[4];
                    byte comman2 = buffer[5];
                    switch (comman1) {
                        case 0x1a:
                            if (comman2 == 0x12) { // 读取定时数据
                                frames.clear();
                                int dataLenght = buffer[7];
                                power = buffer[8];
                                weeks = buffer[9];
                                timerId = buffer[10];
                                int count = buffer[11];
                                int index = 12;
                                for (int i = 0; i < count; i++) {
                                    FrameData data = new FrameData();
                                    byte[] time = new byte[2];
                                    time[0] = buffer[index + 0];
                                    time[1] = buffer[index + 1];
                                    data.setTime(time);

                                    byte[] brightnesses = new byte[5];
                                    brightnesses[0] = buffer[index + 2];
                                    brightnesses[1] = buffer[index + 3];
                                    brightnesses[2] = buffer[index + 4];
                                    brightnesses[3] = buffer[index + 5];
                                    brightnesses[4] = buffer[index + 6];
                                    data.setBrightnesses(brightnesses);

                                    data.setEffect(buffer[index + 7]);

                                    frames.add(data);
                                    index += 8;
                                }
                                if (power == 0x00) {
                                    mOnOff.setChecked(false);
                                } else {
                                    mOnOff.setChecked(true);
                                }
                                mChartView.setFrames(frames);
                            }
                            dismissLoadingView();
                            break;
                        case 0x0f: //下载定时数据回调
                            dismissLoadingView();
                            Toast.makeText(TimerActivity.this, R.string.setting_successful, Toast.LENGTH_SHORT).show();
                            break;
                        case 0x1c: // 定时器开关
                            Log.d(LOGCAT, "成功");
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.timer_layout);
        // 注册广播
        LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter(Constant.TIMER_ACTION));
        initData();
        initView();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 解注册广播
        LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
        mChartView.removeCurrentXChangedListener(this);
    }

    private void initData() {
        String display = getIntent().getStringExtra("DisplayMode");
        if (display != null && display.equals("DisplayMode")) {
            isDisplay = true;
        }

        brightnessCount = getSP(this,"ControlNumber", 5);

        frames = new ArrayList<>();
        FrameData frameData = new FrameData();
        frameData.setTime(new byte[]{0x00, 0x00});
        byte[] brightnesses = {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
        frameData.setBrightnesses(brightnesses);
        frameData.setEffect((byte) 0x00);

        FrameData frameData4 = new FrameData();
        frameData4.setTime(new byte[]{0x18, 0x00});
        byte[] brightnesses4 = {(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
        frameData4.setBrightnesses(brightnesses4);
        frameData4.setEffect((byte) 0x00);

        frames.add(frameData);
        frames.add(frameData4);

    }

    private void initView() {
        mChartView = (ChartView) findViewById(R.id.charView);
        mBack = (ImageView) findViewById(R.id.back);
        mAdd = (ImageView) findViewById(R.id.add);
        mRemove = (ImageView) findViewById(R.id.remove);
        mPrevious = (ImageView) findViewById(R.id.previous);
        mNext = (ImageView) findViewById(R.id.next);
        mPlay = (ImageView) findViewById(R.id.play);
        mPause = (ImageView) findViewById(R.id.pause);
        mDownload = (ImageView) findViewById(R.id.download);
        mDelete = (ImageView) findViewById(R.id.delete);
        mOnOff = (Switch) findViewById(R.id.on_off);

        mChartView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (chartCanTouch) {
                    ChartView chart = (ChartView) view;
                    switch (motionEvent.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            return chart.handleActionDownEvent(motionEvent);
                        case MotionEvent.ACTION_MOVE:
                            return chart.handleActionMoveEvent(motionEvent);
                        case MotionEvent.ACTION_UP:
                            break;
                    }
                    return true;
                }
               return true;
            }
        });
        mChartView.addCurrentXChangedListener(this);

        mOnOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                byte value;
                if (isChecked) {
                    value = 0x01;
                } else {
                    value = 0x00;
                }
                timerOpenOrClose(value);
            }
        });

        mBack.setOnClickListener(this);
        mAdd.setOnClickListener(this);
        mRemove.setOnClickListener(this);
        mPrevious.setOnClickListener(this);
        mNext.setOnClickListener(this);
        mPlay.setOnClickListener(this);
        mPause.setOnClickListener(this);
        mDownload.setOnClickListener(this);
        mDelete.setOnClickListener(this);

        mChartView.setPeriodType(1);
        mChartView.setBrightnessCount(brightnessCount);
        mChartView.setTopBrightnessViewAndVisibility(true);
        mChartView.setVerticalLineVisibility(true);
        mChartView.setFrames(frames);

        if (isDisplay) {
            mDownload.setVisibility(View.GONE);
            mDelete.setVisibility(View.GONE);
            mOnOff.setVisibility(View.GONE);
        } else {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    dismissLoadingView();
                }
            }, 5 * 1000);
            showLoadingView();
            fetchTimer();
        }

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQREST_CODE && resultCode == RESULT_OK) {
            ArrayList<FrameData> dataArrayList = data.getExtras().getParcelableArrayList("data");
            frames = dataArrayList;
            mChartView.setFrames(frames);
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.add:
                if (frames.size() > 24) {
                    Toast.makeText(TimerActivity.this, R.string.frames_limit, Toast.LENGTH_SHORT).show();
                    return;
                }
                Intent intent = new Intent(this, TimerAddOrEditActivity.class);
                Bundle bundle = new Bundle();
                bundle.putParcelableArrayList("data", mChartView.getFrames());
                bundle.putByteArray("time", mChartView.axis2Time());
                intent.putExtras(bundle);
                startActivityForResult(intent, REQREST_CODE);

                break;
            case R.id.remove:
                mChartView.removeFrame();
                frames = mChartView.getFrames();
                break;
            case R.id.previous:
                mChartView.toPreviousFrame();
                break;
            case R.id.next:
                mChartView.toNextFrame();
                break;
            case R.id.play:
                if (frames.size() > 2) {
                    timer = new Timer();
                    openFastPlayMode();
                    count = 0;
                    mChartView.initCurrentX();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            if(count++ < 1440) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        mChartView.updateCurrentX();
                                        int[] values = mChartView.getShowBrightnesses();
                                        startFastPlayMode((byte)values[0], (byte)values[1], (byte)values[2], (byte)values[3], (byte)values[4]);
                                    }
                                });

                            } else {
                                timer.cancel();
                                handler.postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        closeFastPlayMode();
                                        mAdd.setEnabled(true);
                                        mRemove.setEnabled(true);
                                        mPrevious.setEnabled(true);
                                        mNext.setEnabled(true);
                                        mDownload.setEnabled(true);
                                        mDelete.setEnabled(true);
                                        mOnOff.setEnabled(true);
                                        chartCanTouch = true;
                                        mPlay.setVisibility(View.VISIBLE);
                                        mPause.setVisibility(View.GONE);
                                    }
                                }, 300);

                            }
                        }
                    }, 300, 10);
                    mAdd.setEnabled(false);
                    mRemove.setEnabled(false);
                    mPrevious.setEnabled(false);
                    mNext.setEnabled(false);
                    mDownload.setEnabled(false);
                    mDelete.setEnabled(false);
                    mOnOff.setEnabled(false);
                    chartCanTouch = false;
                    mPlay.setVisibility(View.GONE);
                    mPause.setVisibility(View.VISIBLE);
                } else {
                    Toast.makeText(TimerActivity.this, R.string.edit_time_point, Toast.LENGTH_SHORT).show();
                }

                break;
            case R.id.pause:
                if(timer != null) {
                    timer.cancel();
                }
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        closeFastPlayMode();
                    }
                }, 150);

                mAdd.setEnabled(true);
                mRemove.setEnabled(true);
                mPrevious.setEnabled(true);
                mNext.setEnabled(true);
                mDownload.setEnabled(true);
                mDelete.setEnabled(true);
                mOnOff.setEnabled(true);
                chartCanTouch = true;
                mPlay.setVisibility(View.VISIBLE);
                mPause.setVisibility(View.GONE);
                break;
            case R.id.download:
                downloadTimer();
                break;
            case R.id.delete:
                if (mChartView.hasData()) {
                    AlertDialog dialog = new AlertDialog.Builder(TimerActivity.this)
                            .setMessage(R.string.confirm_to_delete)
                            .setNegativeButton(R.string.cancel, null)
                            .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    mChartView.deleteAllFrames();
                                    frames = mChartView.getFrames();
                                }
                            })
                            .create();
                    dialog.show();

                }
                break;
            case R.id.back:
                finish();
                break;
            default:
                break;

        }
    }

    /**
     * 读取定时器
     */
    public void fetchTimer() {
        byte[] bytes = {(byte) 0xC0, 0x0A, 0x11, 0x01, 0x1a, 0x12, 0x00, 0x00, 0x00};
        bytes[8] = RoverGlobal.getInstance().getAddValue(bytes, 8);
        RoverGlobal.getInstance().connect.write(bytes);
    }

    /**
     * 定时器开关
     *
     * @param value
     */
    public void timerOpenOrClose(byte value) {
        byte[] bytes = {(byte) 0xc0, 0x0a, 0x11, 0x01, 0x13, 0x1c, 0x00, 0x01, value, 0x00};
        bytes[9] = RoverGlobal.getInstance().getAddValue(bytes, 9);
        RoverGlobal.getInstance().connect.write(bytes);
    }

    /**
     * 下载定时器
     */
    public void downloadTimer() {
        if (mChartView.hasData()) {
            final View rootView = LayoutInflater.from(this).inflate(R.layout.week_select_layout, null);
            final AlertDialog dialog = new AlertDialog.Builder(this)
                    .setView(rootView)
                    .create();

            monday = (CheckBox) rootView.findViewById(R.id.monday);
            int week = weeks & 1;
            if((week == 1)) {
                monday.setChecked(true);
            }
            monday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(monday.isChecked()) {
                        if(tuesday.isChecked() && wednesday.isChecked() && thursday.isChecked() &&
                                friday.isChecked() && saturday.isChecked() && sunday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            tuesday = (CheckBox) rootView.findViewById(R.id.tuesday);
            week = weeks & 2;
            if((week == 2)) {
                tuesday.setChecked(true);
            }
            tuesday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(thursday.isChecked()) {
                        if(monday.isChecked() && wednesday.isChecked() && thursday.isChecked() &&
                                friday.isChecked() && saturday.isChecked() && sunday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            wednesday = (CheckBox) rootView.findViewById(R.id.wednesday);
            week = weeks & 4;
            if((week == 4)) {
                wednesday.setChecked(true);
            }
            wednesday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(wednesday.isChecked()) {
                        if(tuesday.isChecked() && monday.isChecked() && thursday.isChecked() &&
                                friday.isChecked() && saturday.isChecked() && sunday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            thursday = (CheckBox) rootView.findViewById(R.id.thursday);
            week = weeks & 8;
            if((week == 8)) {
                thursday.setChecked(true);
            }
            thursday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(thursday.isChecked()) {
                        if(tuesday.isChecked() && monday.isChecked() && wednesday.isChecked() &&
                                friday.isChecked() && saturday.isChecked() && sunday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            friday = (CheckBox) rootView.findViewById(R.id.friday);
            week = weeks & 16;
            if((week == 16)) {
                friday.setChecked(true);
            }
            friday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(friday.isChecked()) {
                        if(tuesday.isChecked() && monday.isChecked() && wednesday.isChecked() &&
                                thursday.isChecked() && saturday.isChecked() && sunday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            saturday = (CheckBox) rootView.findViewById(R.id.saturday);
            week = weeks & 32;
            if((week == 32)) {
                saturday.setChecked(true);
            }
            saturday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(saturday.isChecked()) {
                        if(tuesday.isChecked() && monday.isChecked() && wednesday.isChecked() &&
                                thursday.isChecked() && friday.isChecked() && sunday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            sunday = (CheckBox) rootView.findViewById(R.id.sunday);
            week = weeks & 64;
            if((week == 64)) {
                sunday.setChecked(true);
            }
            sunday.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(sunday.isChecked()) {
                        if(tuesday.isChecked() && monday.isChecked() && wednesday.isChecked() &&
                                thursday.isChecked() && friday.isChecked() && saturday.isChecked()) {
                            all.setChecked(true);
                        }
                    } else if(all.isChecked()){
                        all.setChecked(false);
                    }
                }
            });
            all = (CheckBox) rootView.findViewById(R.id.all);
            if(weeks == 127) {
                all.setChecked(true);
            }
            all.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(all.isChecked()) {
                        monday.setChecked(true);
                        tuesday.setChecked(true);
                        wednesday.setChecked(true);
                        thursday.setChecked(true);
                        friday.setChecked(true);
                        saturday.setChecked(true);
                        sunday.setChecked(true);
                    } else {
                        monday.setChecked(false);
                        tuesday.setChecked(false);
                        wednesday.setChecked(false);
                        thursday.setChecked(false);
                        friday.setChecked(false);
                        saturday.setChecked(false);
                        sunday.setChecked(false);
                    }
                }
            });

            cancel = (Button) rootView.findViewById(R.id.cancel);
            cancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });
            download = (Button) rootView.findViewById(R.id.download);
            download.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    byte[] bytes = new byte[1024];
                    bytes[0] = (byte)0xc0;
                    bytes[1] = (byte) 0x0a;
                    bytes[2] = (byte) 0x11;
                    bytes[3] = (byte) 0x01;
                    bytes[4] = (byte) 0x0f; // 指令1
                    bytes[5] = (byte) 0x00; // 指令2
                    bytes[6] = (byte) 0x00; // 数据长度1
                    bytes[7] = (byte) (frames.size() * 8 + 4); // 数据长度2
                    bytes[8] = mOnOff.isChecked() ? (byte) 0x01 : (byte) 0x00; //开关
                    int weekValue = 0;
                    if(monday.isChecked()) {
                        weekValue += 1;
                    }
                    if(tuesday.isChecked()) {
                        weekValue += (1 << 1);
                    }
                    if(wednesday.isChecked()) {
                        weekValue += (1 << 2);
                    }
                    if(thursday.isChecked()) {
                        weekValue += (1 << 3);
                    }
                    if(friday.isChecked()) {
                        weekValue += (1 << 4);
                    }
                    if(saturday.isChecked()) {
                        weekValue += (1 << 5);
                    }
                    if(sunday.isChecked()) {
                        weekValue += (1 << 6);
                    }
                    bytes[9] = (byte) weekValue; // 星期
                    bytes[10] = timerId; //定时器编号
                    bytes[11] = (byte) frames.size(); //总帧数
                    int index = 12;
                    for (int i = 0; i < frames.size(); i++) {
                        FrameData data = frames.get(i);
                        byte[] time = data.getTime();
                        bytes[index++] = time[0];
                        bytes[index++] = time[1];

                        byte[] brightness = data.getBrightnesses();
                        bytes[index++] = brightness[0];
                        bytes[index++] = brightness[1];
                        bytes[index++] = brightness[2];
                        bytes[index++] = brightness[3];
                        bytes[index++] = brightness[4];

                        bytes[index++] = data.getEffect();
                    }
                    bytes[index] = (byte) 0x00; //校验和

                    byte[] finalBytes = new byte[index + 1];
                    for (int i = 0; i < finalBytes.length; i++) {
                        finalBytes[i] = bytes[i];
                    }
                    finalBytes[finalBytes.length - 1] = RoverGlobal.getInstance().getAddValue(finalBytes, finalBytes.length - 1);
                    RoverGlobal.getInstance().connect.write(finalBytes);
                    dialog.dismiss();
                    showLoadingView();
                }
            });

            dialog.show();
        } else {
            Toast.makeText(TimerActivity.this, R.string.edit_time_point, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 进入快播模式
     */
    public void openFastPlayMode () {
        byte[] bytes = {(byte) 0xc0, 0x0a, 0x11, 0x01, 0x25, 0x00, 0x00, 0x00, 0x00};
        bytes[bytes.length - 1] = RoverGlobal.getInstance().getAddValue(bytes, bytes.length - 1);
        RoverGlobal.getInstance().connect.write(bytes);
    }

    /**
     * 发送快播数据
     * @param value1
     * @param value2
     * @param value3
     * @param value4
     * @param value5
     */
    public void startFastPlayMode (byte value1, byte value2, byte value3, byte value4, byte value5) {
        byte[] bytes = {(byte)0xc0, 0x0a, 0x11, 0x01, 0x29, 0x00, 0x00, 0x05, value1, value2, value3, value4, value5, 0x00};
        bytes[bytes.length - 1] = RoverGlobal.getInstance().getAddValue(bytes, bytes.length - 1);
        RoverGlobal.getInstance().connect.write(bytes);
    }

    /**
     * 结束快播模式
     */
    public void closeFastPlayMode () {
        byte[] bytes = {(byte) 0xc0, 0x0a, 0x11, 0x01, 0x27, 0x00, 0x00, 0x00, 0x00};
        bytes[bytes.length - 1] = RoverGlobal.getInstance().getAddValue(bytes, bytes.length - 1);
        RoverGlobal.getInstance().connect.write(bytes);
    }

    @Override
    public void onChageed(boolean b) {
        if (b) {
            mAdd.setImageResource(R.drawable.edit_selector);
        } else {
            mAdd.setImageResource(R.drawable.add_selector);
        }
    }
}
